package com.hotelvip.common.jwt;


import com.hotelvip.common.pojo.JWTToken;
import com.hotelvip.common.utils.JwtUtil;
import com.hotelvip.common.utils.ShiroUtils;
import com.hotelvip.dao.SysMenuMapper;
import com.hotelvip.dao.SysRoleMenuMapper;
import com.hotelvip.dao.SysUserMapper;
import com.hotelvip.dao.SysUserRoleMapper;
import com.hotelvip.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

//@

/**
 *
 * @author Lzh
 * @date 2020/12/1 13:27
 * @Description:shiro的UserRealm类
 */
@Slf4j
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;


    /**
     * 多重写一个support
     * 标识这个Realm是专门用来验证JwtToken
     * 不负责验证其他的token（UsernamePasswordToken）
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        //这个token就是从过滤器中传入的jwtToken
        return token instanceof JWTToken;
    }

    /**负责授权信息的获取和封装*/

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("————权限认证————");
        //1.获取登录用户的权限标识
        SysUser user= ShiroUtils.getUser();
//        SysUser user = (SysUser) principals.getPrimaryPrincipal();
        List<String> permissions= sysMenuMapper.findUserPermissions(user.getId());
        //2.封装查询结果并返回
        Set<String> stringPermissions=new HashSet<>();//会自动对集合内容进行去重操作
        for(String per:permissions) {
            if(per!=null&&!"".equals(per)) {//!StringUtils.isEmpty(per)
                stringPermissions.add(per);
            }
        }
        log.info("stringPermissions="+stringPermissions);
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.setStringPermissions(stringPermissions);
        return info;
    }

    /**
     * 用户身份认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("身份认证");
        String token = (String) authenticationToken.getCredentials();
        long userId = JwtUtil.getUserId(token);
        SysUser user = sysUserMapper.selectById(userId);
        if (userId <= 0 || user == null) {
            throw new AuthenticationException("认证失败！");
        }

                //1.获取登录时输入的账号信息(可以从token中获取)
//        UsernamePasswordToken uToken=(UsernamePasswordToken)token;
//        String username=uToken.getUsername();//登录时输入的用户名

        //2.基于用户查找用户信息并校验
//        String username = (String) jwtUtil.decode(jwt).get("username");
        if(user==null)throw new UnknownAccountException();
        //3.判定用户是否锁定(禁用)
        if(user.getStatus()==0)throw new LockedAccountException();
        return new SimpleAuthenticationInfo(user, token, getName());
    }


//    /**负责认证信息的获取和封装*/
//    @Override
//    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//        log.info("————身份认证方法————");
//        System.out.println("————身份认证方法————");
//        //判断token是否为空
//        String jwtToken = (String) token.getCredentials();
//        System.out.println("认证"+jwtToken);
//
//        //判断
//        String username = JWT.decode(jwtToken).getClaim("username").asString();
////        String username = JwtUtil.getUsername(jwtToken);
//        System.out.println(username);
//        // || !JWTUtil.verify(jwtToken, username)
//        if (username == null) {
//            throw new AuthenticationException("token认证失败！");
//        }
//
////        if (jwt == null) {
////            throw new NullPointerException("jwtToken 不允许为空");
////        }
//        //1.获取登录时输入的账号信息(可以从token中获取)
////        UsernamePasswordToken uToken=(UsernamePasswordToken)token;
////        String username=uToken.getUsername();//登录时输入的用户名
//
//        //2.基于用户查找用户信息并校验
////        String username = (String) jwtUtil.decode(jwt).get("username");
//        SysUser user=sysUserDao.findUserByUserName(username);
//        System.out.println(user);
//        if(user==null)throw new UnknownAccountException();
//        //3.判定用户是否锁定(禁用)
//        if(user.getStatus()==0)throw new LockedAccountException();
//
//
//
//        //4.封装用户信息并返回.
////        return new SimpleAuthenticationInfo(jwtToken, jwtToken, user.getUsername());
//        ByteSource credentialsSalt= ByteSource.Util.bytes(user.getSalt());
////        return new SimpleAuthenticationInfo(token,token,credentialsSalt,username);
//        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(
//                user,//principal 用户身份
//                user.getPassword(),//hashedCredentials 数据库的密码(已加密)
//                credentialsSalt, //credentialsSalt 盐
//                getName());//realmName
//        System.out.println("验证完毕");
//        return info;//返回给securityManager
//    }


//    @Override
//    public void setCredentialsMatcher(
//            CredentialsMatcher credentialsMatcher) {
//        //构建凭证匹配对象
//        HashedCredentialsMatcher cMatcher=
//                new HashedCredentialsMatcher();
//        //设置加密算法
//        cMatcher.setHashAlgorithmName("MD5");
//        //设置加密次数
//        cMatcher.setHashIterations(1);
//        super.setCredentialsMatcher(cMatcher);
//    }


}
